package Shapes;

import processing.core.*;
import processing.xml.*;
import testing.readFile;
import testing.testView.Element;

import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;

import Shapes.Node;


/**
 * @author chen
 * @see represent the impacts
 */

public class pieBall extends shape {

	int x;
	int y;
	String name;
	float size;
	
	int selectfather = -1;
	int selectMinLevel = 10;
	int selectMaxLevel = -1;
	public String filename = "";
	PFont fontA;
	
	public ArrayList<pie> pieTree = new ArrayList<pie>();
	
	public pieBall(PApplet p) {
		super(p);
		// TODO Auto-generated constructor stub
	}

	public void setup(String filename, int x, int y)
	{
	  fontA = parent.loadFont("../resource/Ziggurat-32.vlw");

		// Set the font and its size (in units of pixels)
	  parent.textFont(fontA, 20);
	  this.x = x;
	  this.y = y;
	  this.generateTreeFromFile(filename);
	}
	
	public void setup(String filename, int x, int y, float size, ArrayList<String> im)
	{
	  fontA = parent.loadFont("../resource/Ziggurat-32.vlw");

		// Set the font and its size (in units of pixels)
	  this.filename = filename;
	  parent.textFont(fontA, 20);
	  this.x = x;
	  this.y = y;
	  this.size = size;
	  this.generateTreeFromString(im);
	}

	private void generateTreeFromFile(String filename) {
		// TODO Auto-generated method stub
		readFile rf = new  readFile(parent);
		rf.setup(filename);
		rf.load();
		int num = rf.getLength();
		int piece = rf.getPieceNum();
		float sum = 0.0f;
		for(int i = 1; i<num; i ++){
			String[] pieces =  parent.split(rf.lines[i], '\t');
			sum +=  parent.parseFloat(pieces[1]);
		}
		
		float cal = 0.0f;
		for(int i = 1; i <num; i++){
			
			String[] pieces =  parent.split(rf.lines[i], '\t');
			
			pie p = new pie();
			p.father = -1;
			p.name = pieces[0] + ": " + pieces[1] +"kg";
			float part =  parent.parseFloat(pieces[1]);
			float angle = part*2* parent.PI/sum;
			p.arc = new Arc( x, y,300,cal,angle,0.9f,8.0f,0.1f,i-1,p.name);
			p.level = 1;
			pieTree.add(p);
			
			cal += angle;
		}
		
	}

	public void draw() {
	
		int temproot = this.selectfather;

		while (temproot != -2) {
			for (int i = 0; i < pieTree.size(); i++) {
				if (pieTree.get(i).father == temproot) {
					pieTree.get(i).arc.update();
					pieTree.get(i).arc.display();
				}
			}
			
			if(temproot == -1){
				temproot = -2;
			}else{
				temproot = pieTree.get(temproot).father;
			}
		}
		
	}

	public void Pressed() 
	{
	  for (int i = 0; i < pieTree.size(); i++) { 
		 pieTree.get(i).arc.pressed();
	  } 
	}

	public void Released() 
	{
		for (int i = 0; i < pieTree.size(); i++) { 
			 pieTree.get(i).arc.released();
		   
		  } 
	 
	}

	class Arc {
		// Screen values
		float xpos, ypos;
		float temp_size;
		float size = 20;
		float start = 0;
		float angle = 0;
		boolean over = false;
		boolean move = false;
		int id;

		// Spring simulation constants
		float mass; // Mass
		float k = 0.2f; // Spring constant
		float damp; // Damping
		float rest_size; // Rest position X
		

		// Spring simulation variables
		// float pos = 20.0; // Position
		float velx = 0.0f; // X Velocity
		float vely = 0.0f; // Y Velocity
		float accel = 0; // Acceleration
		float force = 0; // Force
		String name = "";

		int me;

		// Constructor
		Arc(float x, float y, float f, float t, float ang, float d, float m, float k_in, int id,String name) {
		
			xpos  = x;
			ypos  = y;
			size = f;
			temp_size = size;
			rest_size = size;
			
			damp = d;
			mass = m;
			k = k_in;
		
			me = id;
			start = t;
			angle = ang;	
			this.id = id;
			this.name = name;
			
		}

		public void update() {
			if (move) {
				for(int i = 0; i < pieTree.size();i++)
				{
					
					if(pieTree.get(i).father == id){
						pieTree.get(i).arc.rest_size = pieTree.get(i).arc.size*1.5f; 
						//
						if(pieTree.get(id).level> selectMaxLevel)
						{
							selectfather = id;
						}
					}
				}
				
				if(pieTree.get(id).level> selectMaxLevel){
					selectMaxLevel = pieTree.get(id).level;
				}
				
				if(pieTree.get(id).level> selectMinLevel){
					selectMinLevel = pieTree.get(id).level;
				}
			}

			force = -k * (temp_size - rest_size); // f=-ky
			accel = force / mass; // Set the acceleration, f=ma == a=f/m
			vely = damp * (vely + accel); // Set the velocity
			temp_size = temp_size + vely; // Updated position


			if ((over() || move)) {
				over = true;
			} else {
				over = false;
			}
		}

		// Test to see if mouse is over this spring
		public boolean over() {
		
			//judge
			float disx =  parent.mouseX - xpos;
			float disy =  parent.mouseY - ypos;
			
			if(Math.sqrt(disx*disx + disy*disy)> size/2.0)
			{
				return false;
			}
			
			int father = pieTree.get(id).father;
			
			if(father != -1){
				
				if(Math.sqrt(disx*disx + disy*disy)< pieTree.get(father).arc.size/2.0){
					return false;
				}
			}
			
			
			float ang = 0.0f;
			if(disy == 0){
				if(disx >=0)
				{
					ang = 0;
				}else{
					ang =  parent.PI;
				}
			}
			if(disx == 0){
				if(disy >= 0)
				{
					ang =  parent.PI/2;
				}else{
					ang = 3* parent.PI/2;
				}
			}
				
			if(disy > 0)
			{
				if(disx >0){
					ang = (float) Math.atan(disy/disx);
				}else{
					ang =  parent.PI - (float) Math.atan(disy/(-disx));
				}
				
			}else if(disy<0){
				
				if(disx<0){
					ang =  parent.PI +(float)Math.atan(disy/disx);
				}else{
					ang = 2* parent.PI - (float)Math.atan(disy/(-disx));
				}
			}
		
				
			if((start < ang)&&(ang<(start + angle)))
			{
			
				return true;
				
			}else{
				return false;
			}
		}

		
		public void display() {
			if (over) {
				 parent.fill(153);
			} else {
				 parent.fill(255- id*50, 255-id*30, 255-id*10);
			}
			 parent.smooth();
		//	noStroke();
		//	fill(id * 50);
		  
        //  color(PApplet.parseInt(random(255)), PApplet.parseInt(random(255)), PApplet.parseInt(random(255)));
			 parent.arc(xpos, ypos, temp_size, temp_size, start, start + angle);
			
		   if (over) {
			   parent.fill(255);
			   parent.text(name,  parent.mouseX,  parent.mouseY);
			} else {
		
			}

		}

		public void pressed() {
			if (over) {
				move = true;
			
			} else {
				move = false;
			}
		}

		public void released() {
			over = false;
			move = false;
			rest_size = size;
		}
	}
	
//used to record the material flow inventory tree	
class pie{
	int father; // the node of this leave, the root's father == -1
	String name = "";
    Arc arc;
    int level;
}

public void generateTreeFromString(ArrayList<String> im) {
	// TODO Auto-generated method stub
    ArrayList<String> namelist = new ArrayList<String>();
    float sum = 0.0f;
    
    //here, we get one kind of impact as well as its branches
	for(int i=0; i < im.size();i++){
    	String[] ss = im.get(i).split(" ");
    	int find = 0;
       	for(int j = 0; j <namelist.size();j++)
       	{
       		String[] cc = namelist.get(j).split(" ");
       		if(ss[1].equalsIgnoreCase(cc[0]))
       		{
       		   String newc = cc[0]+" "+((Float.parseFloat(cc[1])+Float.parseFloat(ss[2])));
       		   namelist.set(j, newc);
       		   find = 1;
       		}
       	}
       	if(find == 0)
       	{
       		String newc = ss[1]+" " + ss[2];
       		namelist.add(newc);
       	}
   		sum += Float.parseFloat(ss[2]);
    }
	
	//then, we generate a ball, we demantarilly define that the first big ball is the sum
	  pie p0 = new pie();
	  p0.father = -1;
	  p0.name = filename;
	  p0.arc = new Arc(x,y,size,0, 2*parent.PI,0.9f,8.0f,0.1f,0,this.filename);
	  p0.level = 1;
	  pieTree.add(p0);
	  System.out.println(size);
	  float tempend = 0.0f;
	  float tempbegin = 0.0f;

	  for(int i = 0; i <namelist.size();i++){
		
		  String[] ss = namelist.get(i).split(" ");
		  
		  pie p = new pie();
		  p.name = ss[0];
		  p.father = 0;
		  tempbegin = tempend;
		  float added = (Float.parseFloat(ss[1]))*parent.PI*2/sum;
		  tempend +=added;
		  p.arc = new Arc(x,y,size*5/4,tempbegin, added,0.9f,8.0f,0.1f,i+1,ss[0]);
		  p.level = 2;
		  pieTree.add(p);
		  
	  }
}


}
